#ifndef _GB_Z80_H_
#define _GB_Z80_H_

#include "memory.h"
#include "mnemonics.h"

typedef unsigned char UINT8;
typedef unsigned short UINT16;

#define FLAG_Z 0x80
#define FLAG_N 0x40
#define FLAG_H 0x20
#define FLAG_C 0x10


#define REG_B 0x00
#define REG_C 0x01
#define REG_D 0x02
#define REG_E 0x03
#define REG_H 0x04

#define REG_L 0x06
#define REG_A 0x07

#define REG_BC 0x00
#define REG_DE 0x01
#define REG_HL 0x02
#define REG_SP 0x03

extern char *cb_mnemonics[];

extern MEM_MAP memory;

/* si usano le union perché con lo z80 ci sono registri a 8bit che possono essere uniti per farne uno a
   16 bit (per indirizzamento, etc) */
union AF_UNION
{
	struct AF_STRUCT
	{
		UINT8 F;
		UINT8 A;
	} B;
	
	UINT16 AF;
};

union BC_UNION
{
	struct BC_STRUCT
	{
		UINT8 C;
		UINT8 B;
	} B;
	
	UINT16 BC;
};

union DE_UNION
{
	struct DE_STRUCT
	{
		UINT8 E;
		UINT8 D;		
	} B;
	
	UINT16 DE;
};

union HL_UNION
{
	struct HL_STRUCT
	{
		UINT8 L;
		UINT8 H;		
	} B;
	
	UINT16 HL;
};

/* registri */
struct REGS
{
	UINT8** rr;
	UINT16** rrr;
	
	AF_UNION AF;
	BC_UNION BC;
	DE_UNION DE;
	HL_UNION HL;
	UINT16 SP;
	UINT16 PC;
};

/* stato della VM */
struct STATUS
{
	/* ogni quanti cicli di clock si suppone ci possa essere una interrupt */
	UINT16 intPeriod;
};

extern REGS r;
extern STATUS s;

extern void prepare_vm(void);
extern UINT8 fetch_instruction(void);

#endif
